﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;

namespace LuvlyHealer2
{
    using FFACETools;

    public partial class Form1 : Form
    {
        public FFACE _FFACEPL;
        public FFACE _FFACEMonitored;
        public ListBox processids = new ListBox();
        bool pauseActions = false;
        bool castingLock = false;
        int castingSafetyPercentage = 100;


        float plX;
        float plY;
        float plZ;
        
        public Form1()
        {
            InitializeComponent();
            Process[] pol = null;
            pol = Process.GetProcessesByName("pol");
            if (pol.Length < 1)
            {
                MessageBox.Show("FFXI not found");
                System.Environment.Exit(0);
            }
            else
            {
                for (int i = 0; i < pol.Length; i++)
                {
                    POLID.Items.Add(pol[i].MainWindowTitle);
                    POLID2.Items.Add(pol[i].MainWindowTitle);
                    processids.Items.Add(pol[i].Id);
                }
                POLID.SelectedIndex = 0;
                POLID2.SelectedIndex = 0;
                processids.SelectedIndex = 0;
            }
        }

        private void setinstance_Click(object sender, EventArgs e)
        {
// lock Healer Char
            processids.SelectedIndex = POLID.SelectedIndex;
            _FFACEPL = new FFACE((int)processids.SelectedItem);
            POLID.BackColor = System.Drawing.Color.White;
            plPosition.Enabled = true;
//            setinstance2.Enabled = true;
            statusBarUpdate();
// Lock Main char
            processids.SelectedIndex = POLID2.SelectedIndex;
            _FFACEMonitored = new FFACE((int)processids.SelectedItem);
            POLID2.BackColor = System.Drawing.Color.White;
            partyMembersUpdate.Enabled = true;
            actionTimer.Enabled = true;
//            pauseButton.Enabled = true;
//            hpUpdates.Enabled = true;

        }

        private void statusBarUpdate()
        {
            plStatus.Text = _FFACEPL.Player.MainJob.ToString() + _FFACEPL.Player.MainJobLevel.ToString() + " HP: " + _FFACEPL.Player.HPCurrent.ToString() + "/" + _FFACEPL.Player.HPMax.ToString() + " MP: " + _FFACEPL.Player.MPCurrent.ToString() + "/" + _FFACEPL.Player.MPMax.ToString();
        }

        private bool partyMemberUpdateMethod(byte partyMemberId)
        {
            if (_FFACEMonitored.PartyMember[partyMemberId].Active)
            {
                if (_FFACEPL.Player.Zone == _FFACEMonitored.PartyMember[partyMemberId].Zone)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        private void actionTimer_Tick(object sender, EventArgs e)
        {
            // Set array values for GUI "Enabled" checkboxes
            CheckBox[] enabledBoxes = new CheckBox[18];
            enabledBoxes[0] = player0enabled;
            enabledBoxes[1] = player1enabled;
            enabledBoxes[2] = player2enabled;
            enabledBoxes[3] = player3enabled;
            enabledBoxes[4] = player4enabled;
            enabledBoxes[5] = player5enabled;
            enabledBoxes[6] = player6enabled;
            enabledBoxes[7] = player7enabled;
            enabledBoxes[8] = player8enabled;
            enabledBoxes[9] = player9enabled;
            enabledBoxes[10] = player10enabled;
            enabledBoxes[11] = player11enabled;
            enabledBoxes[12] = player12enabled;
            enabledBoxes[13] = player13enabled;
            enabledBoxes[14] = player14enabled;
            enabledBoxes[15] = player15enabled;
            enabledBoxes[16] = player16enabled;
            enabledBoxes[17] = player17enabled;

            if ((_FFACEPL.Player.PosX == plX) && (_FFACEPL.Player.PosY == plY) && (_FFACEPL.Player.PosZ == plZ) && (_FFACEPL.Player.GetLoginStatus == LoginStatus.LoggedIn) && (!pauseActions) && ((_FFACEPL.Player.Status == Status.Standing) || (_FFACEPL.Player.Status == Status.Fighting)))
            {
                if (!pauseActions)
                {
//                    partyMembersUpdate();
                    statusBarUpdate();
                    var playerHpOrder = from k in _FFACEMonitored.PartyMember.Keys
                                        orderby _FFACEMonitored.PartyMember[k].HPPCurrent ascending
                                        select k;

                    foreach (byte id in playerHpOrder)
                    {
                        if (castingPossible(id) && (_FFACEMonitored.PartyMember[id].Active) && (enabledBoxes[id].Checked) && (_FFACEMonitored.PartyMember[id].HPCurrent > 0) && (!castingLock))
                        {
                            if ((_FFACEMonitored.PartyMember[id].HPPCurrent <= Properties.Settings.Default.curePercentage) && (castingPossible(id)))
                            {
                                cureCalculator(id);
                                break;
                            }
                        }
                    }

                    //
                    // Check PL Buffs
                    //
                    if ((Properties.Settings.Default.lightArts) && (!plStatusCheck(StatusEffect.Light_Arts)) && (!plStatusCheck(StatusEffect.Addendum_White)) && (_FFACEPL.Timer.GetAbilityRecast(AbilityList.Light_Arts) == 0))
                    {
                        _FFACEPL.Windower.SendString("/ja \"Light Arts\" <me>");
                        actionLockMethod();
                    }
                    if ((Properties.Settings.Default.afflatusSolace) && (!plStatusCheck(StatusEffect.Afflatus_Solace)) && (_FFACEPL.Timer.GetAbilityRecast(AbilityList.Afflatus_Solace) == 0))
                    {
                        _FFACEPL.Windower.SendString("/ja \"Afflatus Solace\" <me>");
                        actionLockMethod();
                    }
                    else if ((Properties.Settings.Default.sublimation) && (!plStatusCheck(StatusEffect.Sublimation_Activated)) && (!plStatusCheck(StatusEffect.Sublimation_Complete)) && (_FFACEPL.Timer.GetAbilityRecast(AbilityList.Sublimation) == 0))
                    {
                        _FFACEPL.Windower.SendString("/ja \"Sublimation\" <me>");
                        actionLockMethod();
                    }
                    else if ((Properties.Settings.Default.sublimation) && ((_FFACEPL.Player.MPMax - _FFACEPL.Player.MPCurrent) > (_FFACEPL.Player.HPMax * .4)) && (plStatusCheck(StatusEffect.Sublimation_Complete)) && (_FFACEPL.Timer.GetAbilityRecast(AbilityList.Sublimation) == 0))
                    {
                        _FFACEPL.Windower.SendString("/ja \"Sublimation\" <me>");
                        actionLockMethod();
                    }
                    else if ((Properties.Settings.Default.plReraise) && (!plStatusCheck(StatusEffect.Reraise)))
                    {
                        if ((Properties.Settings.Default.plReraiseLevel == 1) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Reraise) == 0))
                        {
                            castSpell("<me>", "Reraise");
                        }
                        else if ((Properties.Settings.Default.plReraiseLevel == 2) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Reraise_II) == 0))
                        {
                            castSpell("<me>", "Reraise II");
                        }
                        else if ((Properties.Settings.Default.plReraiseLevel == 3) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Reraise_III) == 0))
                        {
                            castSpell("<me>", "Reraise III");
                        }
                    }
                    else if ((Properties.Settings.Default.plRefresh) && (!plStatusCheck(StatusEffect.Refresh)))
                    {
                        if ((Properties.Settings.Default.plRefreshLevel == 1) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Refresh) == 0))
                        {
                            castSpell("<me>", "Refresh");
                        }
                        else if ((Properties.Settings.Default.plRefreshLevel == 2) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Refresh_II) == 0))
                        {
                            castSpell("<me>", "Refresh II");
                        }
                    }
                    else if ((Properties.Settings.Default.stoneskin) && (!plStatusCheck(StatusEffect.Stoneskin)) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Stoneskin) == 0))
                    {
                        castSpell("<me>", "Stoneskin");
                    }
                    else if ((Properties.Settings.Default.haste) && (!plStatusCheck(StatusEffect.Haste)) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Haste) == 0))
                    {
                        castSpell("<me>", "Haste");
                    }
                    else if ((Properties.Settings.Default.aquaveil) && (!plStatusCheck(StatusEffect.Aquaveil)) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Aquaveil) == 0))
                    {
                        castSpell("<me>", "Aquaveil");
                    }
                }

            }
        }

        private void cureCalculator(byte partyMemberId)
        {
            if ((Properties.Settings.Default.cure6enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure6amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure_VI) == 0) && (_FFACEPL.Player.MPCurrent > 227))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure VI\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
            else if ((Properties.Settings.Default.cure5enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure5amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure_V) == 0) && (_FFACEPL.Player.MPCurrent > 125))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure V\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
            else if ((Properties.Settings.Default.cure4enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure4amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure_IV) == 0) && (_FFACEPL.Player.MPCurrent > 88))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure IV\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
            else if ((Properties.Settings.Default.cure3enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure3amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure_III) == 0) && (_FFACEPL.Player.MPCurrent > 46))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure III\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
            else if ((Properties.Settings.Default.cure2enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure2amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure_II) == 0) && (_FFACEPL.Player.MPCurrent > 24))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure II\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
            else if ((Properties.Settings.Default.cure1enabled) && ((((_FFACEMonitored.PartyMember[partyMemberId].HPCurrent * 100) / _FFACEMonitored.PartyMember[partyMemberId].HPPCurrent) - _FFACEMonitored.PartyMember[partyMemberId].HPCurrent) > Properties.Settings.Default.cure1amount) && (_FFACEPL.Timer.GetSpellRecast(SpellList.Cure) == 0) && (_FFACEPL.Player.MPCurrent > 8))
            {
                _FFACEPL.Windower.SendString("/ma \"Cure\" " + _FFACEMonitored.PartyMember[partyMemberId].Name);
                castLockMethod();
            }
        }

        private void actionLockMethod()
        {
            castingLock = true;
            actionUnlockTimer.Enabled = true;
            actionTimer.Enabled = false;
        }

        private void castLockMethod()
        {
            castingLock = true;
            castingLockTimer.Enabled = true;
            actionTimer.Enabled = false;
        }

        private void castingLockTimer_Tick(object sender, EventArgs e)
        {
            castingLockTimer.Enabled = false;
            castingStatusCheck.Enabled = true;
        }

        private void Tick_Click(object sender, EventArgs e)
        {
            pauseActions = !pauseActions;

            if (!pauseActions)
            {
                pauseButton.Text = "Pause";
            }
            else if (pauseActions)
            {
                pauseButton.Text = "Paused!";
            }

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 settings = new Form2();
            settings.Show();
        }

        private void castSpell(string partyMemberName, string spellName)
        {
            castLockMethod();
            _FFACEPL.Windower.SendString("/ma \"" + spellName + "\" " + partyMemberName);
        }

        private bool plStatusCheck(StatusEffect requestedStatus)
        {

            bool statusFound = false;

            foreach (StatusEffect status in _FFACEPL.Player.StatusEffects)
            {
                if (requestedStatus == status)
                {
                    statusFound = true;
                }
            }

            return statusFound;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            actionTimer.Enabled = true;
        }

        private void castingLockTimer_Tick_1(object sender, EventArgs e)
        {
            castingLockTimer.Enabled = false;
            castingStatusCheck.Enabled = true;

        }

        private void castingStatusCheck_Tick(object sender, EventArgs e)
        {
            if (_FFACEPL.Player.CastPercentEx >= 75)
            {
                castingStatusCheck.Enabled = false;
                castingUnlockTimer.Enabled = true;
            }
            else if (castingSafetyPercentage == _FFACEPL.Player.CastPercentEx)
            {
                castingStatusCheck.Enabled = false;
                castingUnlockTimer.Enabled = true;
            }

            castingSafetyPercentage = _FFACEPL.Player.CastPercentEx;

        }

        private void castingUnlockTimer_Tick(object sender, EventArgs e)
        {
            castingLock = false;
            actionTimer.Enabled = true;
            castingUnlockTimer.Enabled = false;
        }

        private void actionUnlockTimer_Tick(object sender, EventArgs e)
        {
            castingLock = false;
            actionUnlockTimer.Enabled = false;
            actionTimer.Enabled = true;
        }

        private void plPosition_Tick(object sender, EventArgs e)
        {
            plX = _FFACEPL.Player.PosX;
            plY = _FFACEPL.Player.PosY;
            plZ = _FFACEPL.Player.PosZ;
        }

        private bool castingPossible(byte partyMemberId)
        {
            if ((_FFACEPL.NPC.Distance(_FFACEMonitored.PartyMember[partyMemberId].ID) < 21) && (_FFACEPL.NPC.Distance(_FFACEMonitored.PartyMember[partyMemberId].ID) > 0) && (_FFACEMonitored.PartyMember[partyMemberId].HPCurrent > 0) || (_FFACEPL.Player.ID == _FFACEMonitored.PartyMember[partyMemberId].ID) && (_FFACEMonitored.PartyMember[partyMemberId].HPCurrent > 0))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void partyMembersUpdate_Tick(object sender, EventArgs e)
        {
            if (partyMemberUpdateMethod(0))
            {
                player0enabled.Text = _FFACEMonitored.PartyMember[0].Name;
                player0enabled.Enabled = true;
                player0HP.Text = _FFACEMonitored.PartyMember[0].HPPCurrent.ToString() + "%";
            }
            else
            {
                player0enabled.Enabled = false;
                player0HP.Text = "----";
            }
            if (partyMemberUpdateMethod(1))
            {
                player1enabled.Text = _FFACEMonitored.PartyMember[1].Name;
                player1enabled.Enabled = true;
                player1HP.Text = _FFACEMonitored.PartyMember[1].HPPCurrent.ToString() + "%";
            }
            else
            {
                player1enabled.Text = "Inactive";
                player1enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(2))
            {
                player2enabled.Text = _FFACEMonitored.PartyMember[2].Name;
                player2enabled.Enabled = true;
                player2HP.Text = _FFACEMonitored.PartyMember[2].HPPCurrent.ToString() + "%";
            }
            else
            {
                player2enabled.Text = "Inactive";
                player2enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(3))
            {
                player3enabled.Text = _FFACEMonitored.PartyMember[3].Name;
                player3enabled.Enabled = true;
                player3HP.Text = _FFACEMonitored.PartyMember[3].HPPCurrent.ToString() + "%";
            }
            else
            {
                player3enabled.Text = "Inactive";
                player3enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(4))
            {
                player4enabled.Text = _FFACEMonitored.PartyMember[4].Name;
                player4enabled.Enabled = true;
                player4HP.Text = _FFACEMonitored.PartyMember[4].HPPCurrent.ToString() + "%";
            }
            else
            {
                player4enabled.Text = "Inactive";
                player4enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(5))
            {
                player5enabled.Text = _FFACEMonitored.PartyMember[5].Name;
                player5enabled.Enabled = true;
                player5HP.Text = _FFACEMonitored.PartyMember[5].HPPCurrent.ToString() + "%";
            }
            else
            {
                player5enabled.Text = "Inactive";
                player5enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(6))
            {
                player6enabled.Text = _FFACEMonitored.PartyMember[6].Name;
                player6enabled.Enabled = true;
                player6HP.Text = _FFACEMonitored.PartyMember[6].HPPCurrent.ToString() + "%";
            }
            else
            {
                player6enabled.Text = "Inactive";
                player6enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(7))
            {
                player7enabled.Text = _FFACEMonitored.PartyMember[7].Name;
                player7enabled.Enabled = true;
                player7HP.Text = _FFACEMonitored.PartyMember[7].HPPCurrent.ToString() + "%";
            }
            else
            {
                player7enabled.Text = "Inactive";
                player7enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(8))
            {
                player8enabled.Text = _FFACEMonitored.PartyMember[8].Name;
                player8enabled.Enabled = true;
                player8HP.Text = _FFACEMonitored.PartyMember[8].HPPCurrent.ToString() + "%";
            }
            else
            {
                player8enabled.Text = "Inactive";
                player8enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(9))
            {
                player9enabled.Text = _FFACEMonitored.PartyMember[9].Name;
                player9enabled.Enabled = true;
                player9HP.Text = _FFACEMonitored.PartyMember[9].HPPCurrent.ToString() + "%";
            }
            else
            {
                player9enabled.Text = "Inactive";
                player9enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(10))
            {
                player10enabled.Text = _FFACEMonitored.PartyMember[10].Name;
                player10enabled.Enabled = true;
                player10HP.Text = _FFACEMonitored.PartyMember[10].HPPCurrent.ToString() + "%";
            }
            else
            {
                player10enabled.Text = "Inactive";
                player10enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(11))
            {
                player11enabled.Text = _FFACEMonitored.PartyMember[11].Name;
                player11enabled.Enabled = true;
                player11HP.Text = _FFACEMonitored.PartyMember[11].HPPCurrent.ToString() + "%";
            }
            else
            {
                player11enabled.Text = "Inactive";
                player11enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(12))
            {
                player12enabled.Text = _FFACEMonitored.PartyMember[12].Name;
                player12enabled.Enabled = true;
                player12HP.Text = _FFACEMonitored.PartyMember[12].HPPCurrent.ToString() + "%";
            }
            else
            {
                player12enabled.Enabled = false;
                player12HP.Text = "----";
            }
            if (partyMemberUpdateMethod(13))
            {
                player13enabled.Text = _FFACEMonitored.PartyMember[13].Name;
                player13enabled.Enabled = true;
                player13HP.Text = _FFACEMonitored.PartyMember[13].HPPCurrent.ToString() + "%";
            }
            else
            {
                player13enabled.Text = "Inactive";
                player13enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(14))
            {
                player14enabled.Text = _FFACEMonitored.PartyMember[14].Name;
                player14enabled.Enabled = true;
                player14HP.Text = _FFACEMonitored.PartyMember[14].HPPCurrent.ToString() + "%";
            }
            else
            {
                player14enabled.Text = "Inactive";
                player14enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(15))
            {
                player15enabled.Text = _FFACEMonitored.PartyMember[15].Name;
                player15enabled.Enabled = true;
                player15HP.Text = _FFACEMonitored.PartyMember[15].HPPCurrent.ToString() + "%";
            }
            else
            {
                player15enabled.Text = "Inactive";
                player15enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(16))
            {
                player16enabled.Text = _FFACEMonitored.PartyMember[16].Name;
                player16enabled.Enabled = true;
                player16HP.Text = _FFACEMonitored.PartyMember[16].HPPCurrent.ToString() + "%";
            }
            else
            {
                player16enabled.Text = "Inactive";
                player16enabled.Enabled = false;
            }
            if (partyMemberUpdateMethod(17))
            {
                player17enabled.Text = _FFACEMonitored.PartyMember[17].Name;
                player17enabled.Enabled = true;
                player17HP.Text = _FFACEMonitored.PartyMember[17].HPPCurrent.ToString() + "%";
            }
            else
            {
                player17enabled.Text = "Inactive";
                player17enabled.Enabled = false;
            }

        }

    }
}
